package hyl.core.net;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.util.Arrays;

import hyl.core.run.IFilter;

/**
 * 用于Udp发送和接收
 * 
 * @author 37798955@qq.com
 *
 */
public class MyUdp {
	DatagramSocket _udp;
	public int i包大小 = 8192;

	public MyUdp() {
		try {
			_udp = new DatagramSocket();
		} catch (SocketException e) {
			e.printStackTrace();
		}
	}

	public MyUdp(DatagramSocket udp) {
		_udp = udp;

	}

	public MyUdp(int 本地端口) {
		// 创建DatagramSocket 对象，并指定该程序的通信端口
		try {
			_udp = new DatagramSocket(本地端口);
		} catch (SocketException e) {
			e.printStackTrace();
		}
	}

	private void 应答连接(DatagramPacket receivePacket) {
		try {

			SocketAddress sa = receivePacket.getSocketAddress();
			DatagramPacket sendPacket = new DatagramPacket(new byte[] { 2 }, 1, sa);
			_udp.send(sendPacket);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public static InetSocketAddress connect(String 对方ip, int port) {
		InetSocketAddress addr = MySocket.getIPAddress(对方ip, port);
		return connect(addr);
	}

	public static InetSocketAddress connect(InetSocketAddress addr) {

		try {
			@SuppressWarnings("resource")
			DatagramSocket u = new DatagramSocket();
			DatagramPacket sendPacket = new DatagramPacket(new byte[] { 1 }, 1, addr);
			u.send(sendPacket);
			DatagramPacket receivePacket = new DatagramPacket(new byte[1], 1);
			u.receive(receivePacket);
			byte[] bytes = receivePacket.getData();
			if (Arrays.equals(bytes, new byte[] { 2 }))
				return addr;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public int getI包大小() {
		return i包大小;
	}

	public MyUdp setI包大小(int 大小) {
		this.i包大小 = 大小;
		return this;
	}

	/**
	 * 接收一条数据
	 * 
	 * @return
	 */
	public DatagramPacket receive1() {

		byte[] bt = new byte[i包大小];

		DatagramPacket receivePacket = new DatagramPacket(bt, bt.length);

		try {
			_udp.receive(receivePacket);
		} catch (IOException e) {

			e.printStackTrace();
		}

		return receivePacket;
	}

	boolean isclose = false;

	public void start() {
		isclose = false;
	}

	/**
	 * 需要手动关闭
	 */
	public void close() {
		isclose = true;
		_udp.close();
	}

	/**
	 * 立即终端线程
	 */
	public void Interrupt() {
		Thread.currentThread().interrupt();
	}

	/**
	 * 发送一条数据
	 * 
	 * @param 本地端口
	 * @param 对方ip
	 * @param 对方服务端口
	 * @param 发送数据
	 */
	public void send1(String 对方ip, int 对方服务端口, byte[] 发送数据) {

		try {
			DatagramPacket sendPscket = new DatagramPacket(发送数据, 发送数据.length, InetAddress.getByName(对方ip), 对方服务端口);
			_udp.send(sendPscket);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void send1(SocketAddress 对方ip, byte[] 发送数据) {
		DatagramPacket sendPscket = new DatagramPacket(发送数据, 发送数据.length, 对方ip);
		try {
			_udp.send(sendPscket);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void receive(IFilter<DatagramPacket> call) {
		try {
			while (true) {
				// 接收数据
				byte[] bt = new byte[i包大小];
				DatagramPacket receivePacket = new DatagramPacket(bt, bt.length);
				_udp.receive(receivePacket);
				if (receivePacket.getLength() == 1 && receivePacket.getData()[0] == (byte) 1) {
					应答连接(receivePacket);
					continue;
				}
				if (call != null && call.where(receivePacket)) {
					return;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
